//
//  SystemUpgrade.m
//  cutter
//
//  Created by mac on 16/3/30.
//  Copyright © 2016年 e360. All rights reserved.
//
#import "SystemDownload.h"

//
@interface SystemDownloadCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (weak, nonatomic) IBOutlet UILabel *nameView;
@end
@implementation SystemDownloadCell
@end


//
@interface SystemDownloadItem : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameView;
@property (weak, nonatomic) IBOutlet UIButton *downView;
@end
@implementation SystemDownloadItem
@end

//
@interface SystemDownloadHead : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameView;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end
@implementation SystemDownloadHead
@end

//
@implementation SystemDownload
-(void)viewDidLoad {
    [super viewDidLoad];
    //
    [self.tableView.headerView addTarget:self action:@selector(headerRefresh:) forControlEvents:UIControlEventValueChanged];
    [self.tableView.headerView setTitle:@"正在刷新" forState:TMRefreshStateRefreshing];
    [self.tableView.headerView setTitle:@"释放更新" forState:TMRefreshStatePulling];
    [self.tableView.headerView setTitle:@"下拉刷新" forState:TMRefreshStateNormal];
    //
    [self headerRefresh:nil];
}
-(void)headerRefresh:(TMRefresh*)sender{
    if (sender == nil) {
        sender = self.tableView.headerView;
        [sender beginRefreshing];
    }
    //数据
    __weak SystemDownload *this = self;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [this setCacheFile:pathForLibrary(@"~cache.plist")];
        NSMutableDictionary *source = [NSMutableDictionary dictionaryWithContentsOfFile:this.cacheFile];
        if (source == nil) {
            source = [NSMutableDictionary dictionary];
        }
        [this setSource:source];
        [this loadData:@"base" name:@"基础数据包" icon:@"icon_Downloading.png" source:self.source];
        [this loadData:@"product" name:@"产品数据包" icon:@"icon_Product.png" source:self.source];
        [this loadData:@"community" name:@"楼盘数据包" icon:@"icon-Estate.png" source:self.source];
        [this loadData:@"suit" name:@"套餐数据包" icon:@"icon_Collocation.png" source:self.source];
        [this loadData:@"scheme" name:@"方案数据包" icon:@"icon_Brands.png" source:self.source];
        //
        [this setData:[NSMutableArray array]];
        [this.source writeToFile:this.cacheFile atomically:YES];
        [this.data addObjectsFromArray:this.source.allValues];
        dispatch_async(dispatch_get_main_queue(), ^{
            [sender endRefreshing];
            //
            if (this.data) {
                id root = [NSDictionary dictionaryWithObject:this.data forKey:@"items"];
                UITreeNode *rootNode = [this makeNodesWithData:root level:-1];
                [this.tableView setRootNode:rootNode];
                [TMLoader cancel];
            }
        });
    });
}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
}
//
-(void)loadData:(id)type name:(id)name icon:(id)icon source:(NSMutableDictionary*)source{
    //当前分类
    NSMutableDictionary *dataType = [source objectForKey:type];
    if (dataType == nil) {
        dataType = [NSMutableDictionary dictionary];
        [dataType setValue:name forKey:@"name"];
        [dataType setValue:icon forKey:@"icon"];
        [source setValue:dataType forKey:type];
    }
    //当前版本
    NSString *version = [dataType objectForKey:@"version"];
    if (version == nil) {
        version = @"0";
        [dataType setValue:version forKey:@"version"];
    }
    //当前列表
    NSMutableArray *items = [dataType objectForKey:@"items"];
    if (items == nil) {
        items = [NSMutableArray array];
        [dataType setValue:items forKey:@"items"];
    }
    //接口资源
    NSArray *datas = [AppData getDatas:version type:type];
    for (id temp in datas) {
        //取所有文件
        NSMutableArray *files = [NSMutableArray array];
        NSDictionary *json = [TMJSON parse:[temp objectForKey:@"filejson"]];
        id data = [json objectForKey:@"data"];
        if (data && [data isKindOfClass:NSString.class]) {
            [files addObject:data];
        }
        id package = [json objectForKey:@"package"];
        if (package && [package isKindOfClass:NSArray.class]) {
            [files addObjectsFromArray:package];
        }
        //
        NSMutableDictionary *file = [NSMutableDictionary dictionary];
        [file setValue:[temp objectForKey:@"id"] forKey:@"id"];
        [file setValue:files forKey:@"items"];
        //名字
        id name = [json objectForKey:@"name"];
        id current = [temp objectForKey:@"version_code"];
        if (NO == isEmpty(name)) {
            [file setValue:[NSString stringWithFormat:@"%@-%@", name, current] forKey:@"name"];
        }else{
            id type = [temp objectForKey:@"type"];
            [file setValue:[NSString stringWithFormat:@"%@-%@", type, current] forKey:@"name"];
        }
        //关联
        id relation = [json objectForKey:@"relation_suit"];
        if (NO == isEmpty(relation)) {
            [file setValue:relation forKey:@"relation"];
        }
        [items addObject:file];
        //取最新版本
        if ([current longLongValue] > [version longLongValue]) {
            version = current;
        }
    }
    for (id item in items) {
        [item setValue:@(0) forKey:@"clicked"];
    }
    [dataType setValue:version forKey:@"version"];
}
//UITreeView
-(UITreeNode*)makeNodesWithData:(id)data level:(NSInteger)level{
    static NSInteger identify = 0;
    UITreeNode *nodes=[[UITreeNode alloc] init];
    nodes.idetify=identify++;
    nodes.level = level;
    nodes.value=data;
    nodes.expand = YES;
    //子级列出
    if ([data isKindOfClass:NSDictionary.class]) {
        id child = [data objectForKey:@"items"];
        for (id item in child) {
            [nodes addNode:[self makeNodesWithData:item level:level + 1]];
        }
    }
    return nodes;
}
-(UITableViewCell *)treeView:(UITreeView *)treeView cellForRowAtIndex:(NSInteger)index{
    UITreeNode *node = [treeView nodeAtIndex:index];
    if (node.level == 0) {
        SystemDownloadHead *cell = [treeView dequeueReusableCellWithIdentifier:@"headIdentifier"];
        [cell.iconView setImage:[UIImage imageNamed:[node.value objectForKey:@"icon"]]];
        [cell.nameView setText:[node.value objectForKey:@"name"]];
        return cell;
    }
    if (node.level == 1) {
        SystemDownloadItem *cell = [treeView dequeueReusableCellWithIdentifier:@"itemIdentifier"];
        [cell.downView addTarget:self action:@selector(downTouch:) forControlEvents:UIControlEventTouchUpInside];
        [cell.nameView setText:[node.value objectForKey:@"name"]];
        //
        if ([[node.value objectForKey:@"clicked"] boolValue] == NO) {
            [cell.downView setEnabled:YES];
        }else{
            [cell.downView setEnabled:NO];
        }
        //
        return cell;
    }
    SystemDownloadCell *cell = [treeView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    [cell.nameView setText:node.value];
    [cell.progressView setProgress:0];
    return cell;
}
-(CGFloat)treeView:(UITreeView *)treeView heightForRowAtIndex:(NSInteger)index{
    UITreeNode *node = [treeView nodeAtIndex:index];
    if (node.level == 0) {
        return 54;
    }
    if (node.level == 1) {
        return 60;
    }
    return 72;
}
//下载
-(void)downTouch:(UIButton*)sender{
    UITableViewCell *cell = [self findCell:sender];
    if (cell) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
        if (indexPath) {
            [sender setEnabled:NO];
            //
            UITreeNode *node = [self.tableView nodeAtIndex:indexPath.row];
            [node.value setValue:@(1) forKey:@"clicked"];
            //
            for (UITreeNode *tmp in node.nodes) {
                if (tmp.level == 2) {
                    NSURLRequest *request = [AppData getRequest:tmp.value];
                    [TMLoader load:request name:[tmp.value pathHash] delegate:self cache:2];
                }
            }
            //
            id relation = [node.value objectForKey:@"relation"];
            for (id rid in relation) {
                id child = [self findNode:rid parent:self.tableView.rootNode];
                if (child) {
                    NSInteger row = [self.tableView indexAtNode:child];
                    NSIndexPath * indexPath = [NSIndexPath indexPathForRow:row inSection:0];
                    SystemDownloadItem *down = [self.tableView cellForRowAtIndexPath:indexPath];
                    if (down && [down isKindOfClass:SystemDownloadItem.class]) {
                        [self downTouch:down.downView];
                    }
                }
            }
        }
    }
}
-(id)findNode:(id)nid parent:(UITreeNode*)parent{
    for (UITreeNode *c in parent.nodes) {
        if ([c.value isKindOfClass:NSDictionary.class] && [[c.value objectForKey:@"id"] isEqual:nid]) {
            return c;
        }else{
            id n = [self findNode:nid parent:c];
            if (n) {
                return n;
            }
        }
    }
    return nil;
}
-(id)findCell:(UIView*)sender{
    while (sender) {
        if ([sender isKindOfClass:UITableViewCell.class]) {
            return sender;
        }
        sender = sender.superview;
    }
    return nil;
}
//
-(void)openLoader:(TMLoader *)loader{
    UITreeNode *node = [self nodeWithLoader:loader parent:self.tableView.rootNode];
    if (node) {
        NSInteger row = [self.tableView indexAtNode:node];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        SystemDownloadCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell) {
            [cell.progressView setProgress:0];
        }
    }
}
-(void)completeLoader:(TMLoader *)loader error:(NSError*)error{
    if (error == nil) {
        UITreeNode *node = [self nodeWithLoader:loader parent:self.tableView.rootNode];
        if (node) {
            NSInteger row = [self.tableView indexAtNode:node];
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
            SystemDownloadCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
            if (cell) {
                [cell.progressView setProgress:1];
            }
            //更新数据
            if ([self unzip:loader.file directory:pathForLibrary(@"")]) {
                [self removeNode:node];
                [self.tableView displayNodes];
                [self.source writeToFile:self.cacheFile atomically:YES];
            }
        }
    }else{
        [NSThread sleepForTimeInterval:1];
        [TMLoader load:loader.request name:loader.name delegate:self cache:2];
    }
}
-(void)progressLoader:(TMLoader *)loader bytesLoaded:(unsigned long long)bytesLoaded bytesTotal:(unsigned long long)bytesTotal{
    UITreeNode *node = [self nodeWithLoader:loader parent:self.tableView.rootNode];
    if (node) {
        NSInteger row = [self.tableView indexAtNode:node];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        SystemDownloadCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell) {
            CGFloat progress = (float)bytesLoaded / (float)bytesTotal;
            [cell.progressView setProgress:progress];
        }
    }
}
-(id)nodeWithLoader:(TMLoader*)loader parent:(UITreeNode*)parent{
    NSString *name = [loader.file lastPathComponent];
    for (UITreeNode *node in parent.nodes) {
        if ([node.value isKindOfClass:NSString.class]) {
            if ([[node.value pathHash] isEqualToString:name]) {
                return node;
            }
        }else{
            UITreeNode *temp = [self nodeWithLoader:loader parent:node];
            if (temp != nil) {
                return temp;
            }
        }
    }
    return nil;
}
-(void)removeNode:(UITreeNode*)node{
    UITreeNode *parent = node.parent;
    if (parent && [parent removeNode:node]) {
        NSMutableArray *items = [parent.value objectForKey:@"items"];
        if (items && [items indexOfObject:node.value] != NSNotFound) {
            [items removeObject:node.value];
            if ([items count] == 0 && parent.level > 0) {
                [self removeNode:parent];
            }
        }
    }
}
//解压数据
-(BOOL)unzip:(NSString *)file directory:(NSString*)directory{
    BOOL success = NO;
    NSFileManager *filemanager = [NSFileManager defaultManager];
    if([filemanager fileExistsAtPath:file] && [[[file pathExtension] lowercaseString] isEqualToString:@"zip"]){
        ZipFile *unzipFile = [[ZipFile alloc] initWithFileName:file mode:ZipFileModeUnzip];
        if (unzipFile) {
            success = YES;
            //
            BOOL result = [unzipFile goToFirstFileInZip];
            while (result) {
                @autoreleasepool {
                    FileInZipInfo *info = [unzipFile currentFileInZipInfo];
                    ZipReadStream *stream = [unzipFile readCurrentFileInZip];
                    NSData *data = [stream readDataOfLength:info.length];
                    //
                    if([[[info.name pathExtension] lowercaseString] isEqualToString:@"json"]){
                        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                        NSString *from = [NSString stringWithFormat:@"e360_%@",[info.name stringByDeletingPathExtension]];
                        NSArray *datas = [TMJSON parse:string];
                        [[[TMSQLite shareInstance] transaction] begin];
                        [[TMSQLite shareInstance] query:[self fromDelete:from value:datas]];
                        for (id data in datas) {
                            NSString *sql = [self fromInsert:from data:data];
                            [[TMSQLite shareInstance] query:sql];
                        }
                        [[[TMSQLite shareInstance] transaction] end];
                    }else{
                        NSString *tmp = [directory stringByAppendingPathComponent:info.name];
                        NSString *dir = [tmp stringByDeletingLastPathComponent];
                        if ([filemanager fileExistsAtPath:dir] == NO) {
                            [filemanager createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
                        }
                        [data writeToFile:tmp atomically:YES];
                    }
                    //
                    [stream finishedReading];
                    result = [unzipFile goToNextFileInZip];
                }
            }
            //
            [unzipFile close];
            [filemanager removeItemAtPath:file error:nil];
        }
    }
    return success;
}
//
//数据库操作
-(id)fromFields:(NSString*)from{
    static NSMutableDictionary *instance = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        instance = [[NSMutableDictionary alloc] init];
    });
    NSMutableSet *fields = [instance objectForKey:from];
    if (fields == nil) {
        fields = [NSMutableSet set];
        NSArray *items = [[TMSQLite shareInstance] query:[NSString stringWithFormat:@"PRAGMA table_info(%@)", from]];
        for (id item in items) {
            id name = [item objectForKey:@"name"];
            if (name) {
                [fields addObject:name];
            }
        }
        [instance setValue:fields forKey:from];
    }
    return fields;
}
-(NSString*)fromInsert:(NSString*)from data:(NSDictionary*)data{
    NSMutableSet *fields = [self fromFields:from];
    if ([fields count] > 0) {
        NSMutableArray *keys = [NSMutableArray array];
        NSMutableArray *vals = [NSMutableArray array];
        for (id key in [fields objectEnumerator]) {
            id val = [data objectForKey:key];
            if (val && [NSNull null] != val) {
                if ([val isKindOfClass:[NSString class]]) {
                    NSString *str = [val stringByReplacingOccurrencesOfString:@"'" withString:@"''"];
                    [vals addObject:[NSString stringWithFormat:@"'%@'",str]];
                }else{
                    [vals addObject:val];
                }
                [keys addObject:[NSString stringWithFormat:@"'%@'",key]];
            }
        }
        if (keys.count == vals.count && keys.count > 0) {
            id key = [keys componentsJoinedByString:@","];
            id val = [vals componentsJoinedByString:@","];
            return [NSString stringWithFormat:@"REPLACE INTO %@ (%@) VALUES (%@)", from, key, val];
        }
    }
    return nil;
}
-(NSString*)fromDelete:(NSString*)from value:(id)value {
    if (from) {
        NSMutableSet *fields = [self fromFields:from];
        if (value) {
            if ([fields containsObject:@"uuid"]) {
                NSMutableArray *uuid = [NSMutableArray array];
                if ([value isKindOfClass:NSArray.class]) {
                    for (id item in value) {
                        id uid = [item objectForKey:@"uuid"];
                        if (uid && uid != [NSNull null]) {
                            [uuid addObject:[NSString stringWithFormat:@"'%@'" ,uid]];
                        }
                    }
                }
                if ([value isKindOfClass:NSDictionary.class]) {
                    id uid = [value objectForKey:@"uuid"];
                    if (uid && uid != [NSNull null]) {
                        [uuid addObject:[NSString stringWithFormat:@"'%@'" ,uid]];
                    }
                }
                //
                if ([uuid count] > 0) {
                    NSString *temp = [uuid componentsJoinedByString:@","];
                    if ([fields containsObject:@"delete"]) {
                        return [NSString stringWithFormat:@"DELETE FROM %@ WHERE uuid IN (%@) OR delete=1", from, temp];
                    }
                    return [NSString stringWithFormat:@"DELETE FROM %@ WHERE uuid IN (%@)", from, temp];
                }
            }
        }
        if ([fields containsObject:@"delete"]) {
            return [NSString stringWithFormat:@"DELETE FROM %@ WHERE delete=1", from];
        }
    }
    return nil;
}
@end
